package com.stock_t.service.impl;

import com.stock_t.dto.StockStatisticsRequest;
import com.stock_t.dto.StockStatisticsResponse;
import com.stock_t.mapper.StockPoolMapper;
import com.stock_t.mapper.StockTTransactionMapper;
import com.stock_t.mapper.StockTradingMapper;
import com.stock_t.service.StockStatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.stock_t.controller.StockTradingController.extraInfo;

@Service
@Slf4j
public class StockStatisticsServiceImpl implements StockStatisticsService {

    @Autowired
    private StockTradingMapper stockTradingMapper;

    @Autowired
    private StockTTransactionMapper stockTTransactionMapper;

    @Autowired
    private StockPoolMapper stockPoolMapper;

    @Override
    @Transactional(readOnly = true)
    public StockStatisticsResponse getStockStatistics(String stockCode) {
        StockStatisticsRequest request = new StockStatisticsRequest();
        request.setStockCode(stockCode);
        return getStockStatistics(request);
    }

    @Override
    @Transactional(readOnly = true)
    public StockStatisticsResponse getStockStatistics(StockStatisticsRequest request) {
        try {
            String stockCode = request.getStockCode();
            StockStatisticsResponse response = new StockStatisticsResponse();

            // 设置股票基本信息
            response.setStockInfo(getStockBasicInfo(stockCode));

            // 设置最新数据
            response.setLatestData(getLatestData(stockCode));

            // 设置股数构成
            response.setShareComposition(getShareComposition(stockCode));
            log.info("compositions:{}", response.getShareComposition());

//        // 设置保本价分析
            response.setBreakEvenPrices(getBreakEvenPrices(stockCode));
            log.info("BreakEvenPrices:{}", response.getBreakEvenPrices());

            // 设置股数统计
            response.setShareSummary(getShareSummary(stockCode));
            log.info("ShareSummary:{}", response.getShareSummary());

            // 设置收益汇总
            response.setProfitSummary(getProfitSummary(stockCode));
            log.info("ProfitSummary:{}", response.getProfitSummary());

            // 设置月度收益
            response.setMonthlyProfits(getMonthlyProfits(stockCode));
            log.info("MonthlyProfits:{}", response.getMonthlyProfits());
            // 设置价格分布
            response.setPriceDistribution(getPriceDistribution(stockCode));
            log.info("PriceDistribution:{}", response.getPriceDistribution());

            return response;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("统计出现异常,异常信息为:{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public StockStatisticsResponse.ShareSummary getShareSummary(String stockCode) {
        Map<String, Object> summary = stockTradingMapper.selectShareSummary(stockCode);

        StockStatisticsResponse.ShareSummary shareSummary = new StockStatisticsResponse.ShareSummary();
        if (summary != null) {
            shareSummary.setMaxTotalShares(summary.get("maxTotalShares") != null ?
                    Integer.valueOf(summary.get("maxTotalShares").toString()) : 0);
            shareSummary.setMinTotalShares(summary.get("minTotalShares") != null ?
                    Integer.valueOf(summary.get("minTotalShares").toString()) : 0);
            shareSummary.setCurrentTotalShares(summary.get("currentTotalShares") != null ?
                    Integer.valueOf(summary.get("currentTotalShares").toString()) : 0);
        } else {
            shareSummary.setMaxTotalShares(0);
            shareSummary.setMinTotalShares(0);
            shareSummary.setCurrentTotalShares(0);
        }

        return shareSummary;
    }

    @Override
    @Transactional(readOnly = true)
    public StockStatisticsResponse.StockInfo getStockBasicInfo(String stockCode) {
        StockStatisticsResponse.StockInfo stockInfo = new StockStatisticsResponse.StockInfo();
        stockInfo.setStockCode(stockCode);
        stockInfo.setStockName(stockTradingMapper.selectStockNameByCode(stockCode));
        log.info("stockInfo:{}" + stockInfo);
        return stockInfo;
    }

    @Override
    public StockStatisticsResponse.LatestData getLatestData(String stockCode) {
        Map<String, Object> latestData = stockTradingMapper.selectLatestData(stockCode);
        // 获取做T次数和成功率
        Map<String, Object> tCountAndSuccessRate = stockTTransactionMapper.selectTCountAndSuccessRate(stockCode);
        log.info("latestData:{}" + latestData);
        log.info("tCountAndSuccessRate:{}" + tCountAndSuccessRate);
        StockStatisticsResponse.LatestData data = new StockStatisticsResponse.LatestData();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (latestData != null) {
            data.setTotalShares(latestData.get("totalShares") != null ?
                    Integer.valueOf(latestData.get("totalShares").toString()) : 0);
            data.setTProfit(latestData.get("tProfit") != null ?
                    new BigDecimal(latestData.get("tProfit").toString()) : BigDecimal.ZERO);
            data.setBreakEvenPrice(latestData.get("breakEvenPrice") != null ?
                    new BigDecimal(latestData.get("breakEvenPrice").toString()) : BigDecimal.ZERO);
            data.setCurrentPrice(latestData.get("currentPrice") != null ?
                    new BigDecimal(latestData.get("currentPrice").toString()) : BigDecimal.ZERO);
            data.setProfitLoss(latestData.get("profitLoss") != null ?
                    new BigDecimal(latestData.get("profitLoss").toString()) : BigDecimal.ZERO);
            data.setMarketValue(latestData.get("marketValue") != null ?
                    new BigDecimal(latestData.get("marketValue").toString()) : BigDecimal.ZERO);
            data.setDate(latestData.get("date") != null ? sdf.format((Date)(latestData.get("date"))) : null);
            // 设置做T次数和成功率
            if (tCountAndSuccessRate != null) {
                data.setNumberTrades(tCountAndSuccessRate.get("totalCount") != null ? 
                    tCountAndSuccessRate.get("totalCount").toString() : "0");
                data.setSuccessRate(tCountAndSuccessRate.get("successRate") != null ? 
                    tCountAndSuccessRate.get("successRate").toString() : "0.00");
            }
            if(extraInfo.containsKey(stockCode)){
                data.setProfitLoss(data.getProfitLoss().add(extraInfo.get(stockCode)));
                // 根据盈亏,重新计算保本价格
                // 重新计算保本价格：根据新的盈亏、当前股价和股票数量计算出保本价格
                // 保本价格 = (市值 - 盈亏) / 股票数量
                BigDecimal newBreakEvenPrice = data.getMarketValue().subtract(data.getProfitLoss())
                        .divide(new BigDecimal(data.getTotalShares()), 5, BigDecimal.ROUND_HALF_UP);
                data.setBreakEvenPrice(newBreakEvenPrice);
            }
        } else {
            // 如果没有数据，返回默认值
            data.setTotalShares(0);
            data.setTProfit(BigDecimal.ZERO);
            data.setBreakEvenPrice(BigDecimal.ZERO);
            data.setCurrentPrice(BigDecimal.ZERO);
            data.setProfitLoss(BigDecimal.ZERO);
            data.setMarketValue(BigDecimal.ZERO);
            data.setDate("");
            data.setNumberTrades("0");
            data.setSuccessRate("0.00");
        }

        return data;
    }

    @Override
    @Transactional(readOnly = true)
    public List<StockStatisticsResponse.MonthlyProfit> getMonthlyProfits(String stockCode) {
        // 获取当前年份
        int currentYear = LocalDate.now().getYear();
        
        // 查询数据库中的月度收益数据
        List<Map<String, Object>> monthlyData = stockTTransactionMapper.selectMonthlyProfits(stockCode);
        
        // 创建月份到收益的映射
        Map<String, BigDecimal> monthlyProfitMap = monthlyData.stream()
                .collect(Collectors.toMap(
                    item -> item.get("month").toString(),
                    item -> new BigDecimal(item.get("profit").toString())
                ));
        
        // 生成完整的12个月数据
        List<StockStatisticsResponse.MonthlyProfit> result = new ArrayList<>();
        
        for (int month = 1; month <= 12; month++) {
            String monthKey = String.format("%d-%02d", currentYear, month);
            
            StockStatisticsResponse.MonthlyProfit monthlyProfit = new StockStatisticsResponse.MonthlyProfit();
            monthlyProfit.setMonth(monthKey);
            
            // 如果数据库中有该月份数据，使用实际值；否则使用0
            BigDecimal profit = monthlyProfitMap.getOrDefault(monthKey, BigDecimal.ZERO);
            monthlyProfit.setProfit(profit);
            
            result.add(monthlyProfit);
        }
        
        return result;
    }

    @Override
    @Transactional(readOnly = true)
    public List<StockStatisticsResponse.ShareItem> getShareComposition(String stockCode) {
        List<Map<String, Object>> compositions = stockPoolMapper.selectShareComposition(stockCode);

        return compositions.stream()
                .map(item -> {
                    StockStatisticsResponse.ShareItem shareItem = new StockStatisticsResponse.ShareItem();
                    shareItem.setShares(Integer.valueOf(item.get("shares").toString()));
                    shareItem.setPrice(new BigDecimal(item.get("price").toString()));
                    return shareItem;
                })
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<StockStatisticsResponse.BreakEvenItem> getBreakEvenPrices(String stockCode) {
        List<Map<String, Object>> breakEvenPrices = stockTradingMapper.selectBreakEvenPrices(stockCode);
        return breakEvenPrices.stream()
                .map(item -> {
                    StockStatisticsResponse.BreakEvenItem breakEvenItem = new StockStatisticsResponse.BreakEvenItem();
                    breakEvenItem.setShares(Integer.valueOf(item.get("shares").toString()));
                    breakEvenItem.setBreakEvenPrice(new BigDecimal(item.get("breakEvenPrice").toString()));
                    return breakEvenItem;
                })
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public StockStatisticsResponse.ProfitSummary getProfitSummary(String stockCode) {
        Map<String, Object> summary = stockTTransactionMapper.selectProfitSummary(stockCode);

        StockStatisticsResponse.ProfitSummary profitSummary = new StockStatisticsResponse.ProfitSummary();
        if (summary != null && summary.size() > 0) {
            profitSummary.setTotalTProfit(new BigDecimal(summary.get("totalTProfit").toString()));
            profitSummary.setCurrentMonthTProfit(new BigDecimal(summary.get("currentMonthTProfit").toString()));
            profitSummary.setMaxMonthlyTProfit(new BigDecimal(summary.get("maxMonthlyTProfit").toString()));
            profitSummary.setMaxTProfit(new BigDecimal(summary.get("maxTProfit").toString()));
            profitSummary.setMinTProfit(new BigDecimal(summary.get("minTProfit").toString()));
        }

        return profitSummary;
    }

    @Override
    @Transactional(readOnly = true)
    public StockStatisticsResponse.PriceDistribution getPriceDistribution(String stockCode) {
        List<Map<String, Object>> priceDaysList = stockTradingMapper.selectPriceDaysMap(stockCode);

        StockStatisticsResponse.PriceDistribution distribution = new StockStatisticsResponse.PriceDistribution();
        distribution.setPriceDaysList(priceDaysList != null ? priceDaysList : new ArrayList<>());
        distribution.setDaysWithCurrentPrice(stockTradingMapper.countDaysWithCurrentPrice(stockCode));
        distribution.setTotalRecords(stockTradingMapper.countTotalRecords(stockCode));

        return distribution;
    }
}